﻿using I3.AgenteIA.Dominio.Gramatica;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.Collections.Generic;
using Moq;

namespace I3.AgenteIA.Dominio.Teste.Gramatica
{
    
    
    /// <summary>
    ///This is a test class for SentencaFactoryTest and is intended
    ///to contain all SentencaFactoryTest Unit Tests
    ///</summary>
    ///<remarks>
    ///
    /// Testes de criação de sentenças infiviuais
    /// 
    /// - InterpretarTest_Caso1
    /// Deverá analisar uma frase simples composta por apenas uma palavra e SEM UM finalizador.
    /// 
    /// - InterpretarTest_Caso2
    /// Deverá analisar uma frase simples composta por apenas uma palavra e COM UM finalizador qualquer.
    /// 
    /// - InterpretarTest_Caso3
    /// Deverá analisar uma frase simples composta por apenas uma palavra e COM UM finalizador qualquer sequencial.
    /// 
    /// - InterpretarTest_Caso4
    /// Deverá analisar uma frase multipla composta por apenas uma palavra e SEM UM finalizador.
    /// 
    /// - InterpretarTest_Caso5
    /// Deverá analisar uma frase multipla composta por apenas uma palavra e COM UM finalizador qualquer.
    /// 
    /// - InterpretarTest_Caso6
    /// Deverá analisar uma frase multipla composta por apenas uma palavra e COM UM finalizador qualquer sequencial.
    /// 
    /// </remarks>
    [TestClass()]
    public class SentencaInterpreterTest
    {
        /// <summary>
        /// Armazena os finalizadores usados no teste
        /// </summary>
        private IEnumerable<Sinal> finalizadores = new Sinal[] { 
                new Sinal(".") { EhFinalizador = false }, 
                new Sinal("!") { EhFinalizador = false },
                new Sinal("?") { EhFinalizador = false } };

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso1()
        {
            InterpretarTest_Execucao("simples", new string[] { "simples" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso2()
        {
            InterpretarTest_Execucao("simples!", new string[] { "simples!" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso3()
        {
            InterpretarTest_Execucao("simples!!!", new string[] { "simples!!!" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso4()
        {
            InterpretarTest_Execucao("frase composta", new string[] { "frase composta" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso5()
        {
            InterpretarTest_Execucao("frase composta?", new string[] { "frase composta?" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso6()
        {
            InterpretarTest_Execucao("frase composta???", new string[] { "frase composta???" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso7()
        {
            InterpretarTest_Execucao("frase composta? claro que é", new string[]{ 
                "frase composta?", "claro que é" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso8()
        {
            InterpretarTest_Execucao("frase composta? claro que é!", new string[]{ 
                "frase composta?", "claro que é!" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso9()
        {
            InterpretarTest_Execucao("frase composta? claro que é!!!", new string[]{ 
                "frase composta?", "claro que é!!!" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso10()
        {
            InterpretarTest_Execucao("frase composta??? claro que é!!!", new string[]{ 
                "frase composta???", "claro que é!!!" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso11()
        {
            // Declara as variaveis auxiliares do teste
            InterpretarTest_Execucao("frase composta. separação de frase, com virgula", new string[]{ 
                "frase composta.", "separação de frase, com virgula" });
        }

        [TestMethod]
        [DeploymentItem("I3.AgenteIA.Dominio.dll")]
        public void InterpretarTest_Caso12()
        {
            // Declara as variaveis auxiliares do teste
            InterpretarTest_Execucao("uma url www.google.com.br", new string[]{ 
                "uma url www.google.com.br" });
        }

        private void InterpretarTest_Execucao(string texto, string[] sentencas)
        {
            // Declara os objetos auxiliares do teste
            Oracao oracao = new Oracao(texto);
            
            
            // Declara os objetos mock do teste
            var repositorio = new Mock<IRepositorioGramatica>();
            
            // Configura a execução dos métodos mock
            repositorio.Setup(o => o.GetSinalByFinalizador(true)).Returns(finalizadores);

            // Realizada a execução do teste
            SentencaInterpreter_Accessor interpreter = new SentencaInterpreter_Accessor(repositorio.Object);
            IEnumerable<Sentenca> atual = interpreter.Interpretar(oracao);

            // Realiza os asserts no retorno do metodo, verificando a quantidade de sentenças
            // retornadas e se todos os textos esperados foram retornados.
            Assert.AreEqual(sentencas.Count(), atual.Count());       
            foreach (string sentenca in sentencas)
                Assert.IsTrue((atual.Count(o => o.Texto == sentenca) == 1));
        }
    }
}
